// 条件类型
type IsEqual<T> = T extends true ? 1 : 2;
type A = IsEqual<true>;
type B = IsEqual<false>;
type C = IsEqual<"string">;

// 泛型约束
function add(source: number, add: number) {
  if (typeof source !== "number" || typeof add !== "number") {
    throw new Error("Invalid arguments");
  }
  return source + add;
}

type ResStatus<ResCode extends number> = ResCode extends 10000 | 10001 | 10002
  ? "success"
  : "fail";

// type status3 = ResStatus<"10004">;
// 在泛型中传入不符合条件的类型会直接报错

// 函数中的泛型
function handle<T>(input: T): T {
  return input;
}

const author = "wangbin22";
const handleAuthor = handle(author);

// 函数中的泛型2
function swap<T, U>([start, end]: [T, U]): [U, T] {
  return [end, start];
}

const swap1 = swap(["你好", 2]);

// class Dog{
//   eat(a:string){}
// }
// class Cat{
//   eat(b:number){}
// }
// function call(cat: Cat){};
// call(new Dog())

// type USD = number;
// type CNY = number;

// const CNYCount: CNY = 10;
// const USDCount: USD = 100;

// function addCNY(source: CNY, input: CNY) {
//   return source + input;
// }
// addCNY(CNYCount, USDCount);

// export declare class TagProtector<T extends string> {
//   protected __tag__: T;
// }

// export type Nominal<T, U extends string> = T & TagProtector<U>;

// type USD = Nominal<number, "USD">;
// type CNY = Nominal<number, "CNY">;

// const CNYCount = 10 as CNY;
// const USDCount = 100 as USD;
// function addCNY(source: CNY, input: CNY) {
//   return source + input;
// }
// addCNY(CNYCount, USDCount);

// class CNY {
//   private __tag!: void;
//   constructor(public value: number) {}
// }
// class USD {
//   private __tag!: void;
//   constructor(public value: number) {}
// }
// let cny = new CNY(1000);
// let usd = new USD(1000);
// function count(param1: CNY, param2: CNY) {
//   return param1.value + param2.value;
// }
// count(cny, usd);

/// 多泛型实例- map
// function map<U, V>(list: U[], callback: (e: U, i?: number) => V): V[] {
//   let result:V[] = [];
//   for (let i = 0; i < list.length; i++) {
//     const item = list[i];
//     result.push(callback(item, i));
//   }
//   return result;
// }
// const arr = [1, 2, 3, 4, 5];
// const t1 = map(arr, (item, i) => `<span>${item}-${i}<span>`);
// console.log(t1);

// 受限的泛型
function myTuple<T extends unknown[]>(...ts: T) {
  return ts;
}
const ts = myTuple(1, 2, 3, 4);

export {};
